EventChannel:用於接收一系列訊息,這些訊息被包裝到 Stream 中,receiveBroadcastStream
返回一個 Stream 物件,可以在 Stream 上新增監聽者,然後開始呼叫 Native 端的 listen
方法後,Native 中對應的 EventChannel
就會開始處理訊息,在處理的過程中可以傳送多條訊息,這些訊息在傳到 Flutter 後都會被加入到 Stream 中,然後通知所有的監聽者,其中 EventChannel
有以下幾種特色
在 listen
開始之前,Native 端的 EventChannel
無法主動開始運作,當 Flutter 中 Stream 的第一個監聽者成功新增時,才會向 Native 呼叫 listen
方法,此時二者之間建立連線並開始運作
在 listen
的過程中間,二者並不能進行交流,Native 層呼叫 listen
方法後就開始不斷發送訊息,Flutter 中也只能通過 Stream 不斷接收訊息
二者都可以主動結束連線,在 Native 中可以呼叫 EventSink.endOfStream
結束連線,在 Flutter 中移除 Stream 的所有監聽者也可以結束連線。如果需要再次建立連線,就需要向 Stream 中新增監聽者
在EventChannel
中,二者向對方傳送訊息時都不需要接收返回的結果,而是直接通過新的send
途徑向對方傳送訊息,這是 EventChannel
與其他兩種Platflrm Channel 最大的不同,EventChannel
呼叫receiveBroadcastStream
來取得一個 Stream 物件,後續上層主要是通過在 Stream 中新增監聽來完成對 Native 端訊息的接收等操作
Stream<dynamic> receiveBroadcastStream([ dynamic arguments ]) {
final MethodChannel methodChannel = MethodChannel(name, codec);
StreamController<dynamic> controller;
controller = StreamController<dynamic>.broadcast(onListen: () async {
defaultBinaryMessenger.setMessageHandler(name, (ByteData reply) async {
if (reply == null) {
controller.close();
} else {
try {
controller.add(codec.decodeEnvelope(reply));
} on PlatformException catch (e) {
controller.addError(e);
}
}
return null;
});
try {
await methodChannel.invokeMethod<void>('listen', arguments);
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context: ErrorDescription('while activating platform stream on channel $name'),
));
}
}, onCancel: () async {
defaultBinaryMessenger.setMessageHandler(name, null);
try {
await methodChannel.invokeMethod<void>('cancel', arguments);
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context: ErrorDescription('while de-activating platform stream on channel $name'),
));
}
});
return controller.stream;
}
receiveBroadcastStream
在呼叫之後會先生成一個 MethodChannel
來呼叫 Native 端方法,之後建立一個 StreamController
,在StreamController
的 onListen
函式中註冊了MessageHandler
來處理訊息的接收,在接收到訊息之後會將其存到 StreamController
中,StreamController
負責將訊息傳送到它的監聽者們
之後就是向 Native 呼叫 listen
方法,然後開始接收訊息,在onCancel
函式中透過呼叫Native 的cancel
方法來取消訊息接收,讓 Native 中的 EventChannel
做一些結尾工作等
而Native 端(以 android 為例),EventChannel
通過呼叫setStreamHandler
方法,StreamHandler
會由上層實作並提供,負責具體的處理邏輯,它有 onListen
和 onCancel
兩個方法,onListen
提供了 arguments(引數)和 events(用於傳送訊息、報錯和結束連線),而 onCancel
只提供了 argments 引數
public interface StreamHandler {
void onListen(Object arguments, EventSink events);
void onCancel(Object arguments);
}
在setStreamHandler
中,EventChannel
將 StreamHandler
封裝到IncomingStreamRequestHandler
中,IncomingStreamRequestHandler
中的onMessage
就是Native 端接收到訊息之後的回撥方法,當接收到呼叫listen
方法的訊息時會呼叫onListen
函式,在 onListen
中會再呼叫 StreamHandler
的 onListen
函式,Native 中的 EventChannel
也可以通過呼叫EventSink.endOfStream
來結束連線,它會向 Flutter 中傳送一個null
訊息,在 Flutter 中接收到null
訊息時便會呼叫 StreamController.close
來結束接收訊息
以上就對Flutter 與 Native 的通訊處理做了初步的介紹,接下來讓我們來創建一個Flutter Plugin 來實作看看吧